const router = require('koa-router')();
const utils = require('../lib/utils');

/**
 * 获取角色拥有的权限，不传roleId，则默认获取当前角色menus list
 */
router.get('/role', httpResult.resp(async ctx => {
    let account = ctx.session.admin;
    let roleId = ctx.request.query.role || account.role;
    //根据用户角色，到角色表获取用户的菜单权限。
    let role = await models.role.findOne({_id : roleId});
    ctx.assert(role, 'user account did not set any role, no available menus');

    let result;
    if(role.type === 0){
        result = await models.menu.find().lean();
    }else{
        result = await models.menu.find({_id : {$in : role.menus}}).lean();
    }
    return result;
}));
/**
 * 新增菜单
 */
router.post('/add', httpResult.resp(async ctx => {
    let menu = ctx.request.body;
    let result = await models.menu.create(menu);
    return result;
}));

/**
 * 获取菜单列表BY pid, 只向下查找一级
 */
router.get('/list', httpResult.resp(async ctx => {
    let pid = ctx.request.query.pid;
    let resultList = await models.menu.find().sort({'sort': -1}).lean();
    console.log('list : ',resultList);
    let arr = getChildrenArray(pid, resultList);

    arr.forEach(item => {
        if(getChildrenArray(item._id, resultList).length > 0){
            item.hasChildren = true;
        }else{
            item.hasChildren = false;
        }
    });

    return arr;
}));

/**
 * 更新菜单设置
 */
router.put('/update/:id', httpResult.resp(async ctx => {
    let id = ctx.params.id;
    let menu = ctx.request.body;

    return await models.menu.findOneAndUpdate({_id : id}, {$set : menu}, {new : true});
}));

/**
 * 删除本节点以及相关子节点
 */
router.delete('/:id', httpResult.resp(async ctx => {
    let admin = ctx.session.admin;
    let id = ctx.params.id;
    let role = await models.role.findOne({_id : admin.role});
    ctx.assert(role && role.type === 0, 'no permission, only super admin can remove menu');

    let allMenus = await models.menu.find();
    let ids = [id];
    function getChildren(pid, array) {
        array.forEach(item => {
            if (item.pid == pid) {
                ids.push(item._id)
                getChildren(item.id, array)
            }
        });
    }
    getChildren(id, allMenus);
    let dbResult = await models.menu.remove({_id : {$in : ids}});
    //TODO 如果还有角色使用已删除菜单，一并删除。
    return dbResult.deletedCount;
}))

router.get('/all', httpResult.resp(async ctx => {
    let all = await models.menu.find().lean();
    return toTree(all);
}));


function getChildrenArray(pid, arr) {
    let newArr = [];
    for (let item of arr) {
        if (item.pid == pid)
            newArr.push(item);
    }
    return newArr;
}

function toTree(data) {
    // 删除 所有 children,以防止多次调用
    data.forEach(function(item) {
        delete item.children;
    });
    // 将数据存储为 以 id 为 KEY 的 map 索引数据列
    let map = {};
    data.forEach(function(item) {
        map[item._id] = item;
    });
    //console.log(map);
    let val = [];
    data.forEach(function(item) {
        // 以当前遍历项，的pid,去map对象中找到索引的id
        item.meta = {
            title : item.title, 
            icon : item.icon, 
            activeMenu : item.activeMenu, 
            roles: [],
            noCache : item.noCache
        }
        if(item.redirect != 'noRedirect'){
            delete item.redirect;
        }
        delete item.icon;
        delete item.noCache;
        let parent = map[item.pid];
        // 好绕啊，如果找到索引，那么说明此项不在顶级当中,那么需要把此项添加到，他对应的父级中
        if (parent) {
            if(item.type === 2){//菜单
                (parent.children || (parent.children = [])).push(item);
                parent.hasChildren = true;
            }else if(item.permissions !== '' && item.type === 3){//按钮
                let parent = map[item.pid];
                if(parent && parent.meta !== undefined){
                    (parent.meta.roles || (parent.meta.roles = [])).push(item.permissions);
                    parent.hasChildren = false;
                }
            }
            
        } else {
            //如果没有在map中找到对应的索引ID,那么直接把 当前的item添加到 val结果集中，作为顶级
            val.push(item);
        }
    });
    return val;
}

module.exports = router;
